package com.john.demo.web;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Map;

/**
 * 本Servlet用于验证基于nginx反向代理，能否将请求头参数、POST请求参数的正常传过来
 */
@WebServlet("/proxy")
@MultipartConfig
@Slf4j
public class TestProxyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        log.info("接到【GET】请求....");
        String requestURI = req.getRequestURI();
        log.info("requestURI: " + requestURI);
        printHeaderParams(req);
        printRequestParams(req);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        log.info("接到【POST】请求....");
        String requestURI = req.getRequestURI();
        log.info("requestURI: " + requestURI);
        printHeaderParams(req);
        String contentType = req.getContentType();
        log.info("请求mime类型：" + contentType);
        if(contentType.contains("x-www-form-urlencoded")) {
            printRequestParams(req);
        } else if(contentType.contains("application/json")) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(req.getInputStream(), "UTF-8"));
            StringBuilder jsonData = new StringBuilder();
            String line = null;
            while((line = reader.readLine()) != null) {
                jsonData.append(line);
                jsonData.append("\n");
            }
            log.info("请求数据：\n" + jsonData);
        } else if(contentType.contains("form-data")) {
            // 文件上传请求
            log.info("普通参数：");
            printRequestParams(req);
            log.info("文件数据：");
            Collection<Part> parts = req.getParts();
            if(parts != null) {
                for(Part part : parts) {
                    if(part.getSubmittedFileName() != null) {
                        log.info("文件名：" + part.getSubmittedFileName() +", 文件类型：" + part.getContentType() + ", 文件大小：" + part.getSize());
                    }
                }
            } else {
                log.info("没有上传文件");
            }

        } else {
            BufferedInputStream in = new BufferedInputStream(req.getInputStream());
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int len = -1;
            byte[] buffer = new byte[10240];
            while((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            log.info("读到二进制数据，大小：" + out.toByteArray().length + " byte.");
        }

    }

    private void printRequestParams(HttpServletRequest req) {
        Map<String, String[]> parameterMap = req.getParameterMap();
        for(String key : parameterMap.keySet()) {
            log.info("参数" + key+": " + String.join(",", parameterMap.get(key)));
        }
    }

    private void printHeaderParams(HttpServletRequest req) {
        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String headerKey = headerNames.nextElement();
            log.info("请求头参数" + headerKey+": " + req.getHeader(headerKey));
        }
    }

}
